package com.mike.uaa.core;

import lombok.Getter;

import java.time.Instant;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.function.Consumer;

/**
 * @author z
 */
@Getter
public class DefaultAuthenticationToken extends AbstractAuthenticationToken {

    private static final long serialVersionUID = 7103900723117324877L;

    private String tokenValue;
    private Instant issuedAt;
    private long expiresIn;
    private final Object principal;

    /**
     * 使用提供的颁发机构数组创建令牌。
     *
     * @param authorities 此身份验证对象表示的主体的 GrantedAuthority 集合。
     */
    private DefaultAuthenticationToken(Object principal, Collection<? extends GrantedAuthority> authorities) {
        super(authorities);
        this.principal = principal;
    }


    @Override
    public String getTokenValue() {
        return tokenValue;
    }

    @Override
    public Instant getIssuedAt() {
        return issuedAt;
    }

    @Override
    public long getExpiresIn() {
        return expiresIn;
    }

    @Override
    public Object getPrincipal() {
        return principal;
    }

    @Override
    public Object getCredential() {
        if (isAuthenticated()) {
            return ((User) principal).getPassword();
        }
        return null;
    }

    public static Builder builder() {
        return new Builder();
    }

    public static class Builder {

        private Object principal;
        private List<GrantedAuthority> authorities = new ArrayList<>();
        private boolean authenticated = false;
        private String tokenValue;
        private Instant issuedAt;
        private long expiresIn;

        public Builder principal(Object principal) {
            this.principal = principal;
            return this;
        }

        public Builder authenticated() {
            this.authenticated = true;
            return this;
        }

        public Builder authenticated(boolean authenticated) {
            this.authenticated = authenticated;
            return this;
        }

        public Builder tokenValue(String tokenValue) {
            this.tokenValue = tokenValue;
            return this;
        }

        public Builder issuedAt(Instant issuedAt) {
            this.issuedAt = issuedAt;
            return this;
        }

        public Builder expiresIn(long expiresIn) {
            this.expiresIn = expiresIn;
            return this;
        }

        public Builder authorities(Collection<? extends GrantedAuthority> authorities) {
            this.authorities = new ArrayList<>(authorities);
            return this;
        }

        public Builder authorities(Consumer<Collection<GrantedAuthority>> authoritiesConsumer) {
            authoritiesConsumer.accept(this.authorities);
            return this;
        }

        public DefaultAuthenticationToken build() {
            DefaultAuthenticationToken authenticationToken = new DefaultAuthenticationToken(principal, authorities);
            authenticationToken.setAuthenticated(authenticated);
            authenticationToken.tokenValue = tokenValue;
            authenticationToken.issuedAt = issuedAt;
            authenticationToken.expiresIn = expiresIn;
            return authenticationToken;
        }
    }
}
